// #include<iostream>
// using namespace std;
// int main()
// {

//     int i=0;
//     //对象流入输出设备，在显示器中打印对象中存储的值
//     cout<<i<<endl;
//     cerr<<i<<endl;
//     clog<<i<<endl;
//     return 0;

// }

class Date
{
public:
	Date(int _year = 0, int _month = 0, int _day = 0)
		: year(_year)
		, month(_month)
		, day(_day)
	{}

	operator bool()
	{
		if (year < 1)
			return false;
		else
			return true;
	}

	friend ostream& operator>>(ostream& os, const Date& d);
	friend istream& operator<<(istream& is, Date& d);
public:
	int year;
	int month;
	int day;
};

ostream& operator<<(ostream& os, const Date& d)
{
	return os << d.year << " " << d.month << " " << d.day;
}

istream& operator>>(istream& is, Date& d)
{
	return is >> d.year >> d.month >> d.day;
}
// 转换函数：对该对象进行判断时，流对象会自动调用给对象，返回一个bool值
void Operator_Bool()
{
	Date d;
	d = 20;
	if (d)
		cout << "yes" << endl;
	else
		cout << "no" << endl;
}

// void Test1()
// {
// 	Date d;
// 	cin >> d;
// 	cout << d << endl;
// }
// void Test2()
// {
// 	// 自动识别类型的本质--函数重载
// 	// 内置类型可以直接使用--因为库里面ostream类型已经实现了
// 	int i = 1;
// 	double j = 2.2;
// 	cout << i << endl;
// 	cout << j << endl;
// }



// int  main()
// {
//     Date d;
//     // cin>>d;
//     // cout<<d<<endl;

// 	//Test1();
// 	//Test2();

// 	Operator_Bool();

//     return 0;
// }


#include <iostream>
#include <fstream>
#include<string>
#include<fstream>
using namespace std;

// int main()
// {
// 	// 以读的方式打开文件
// 	ifstream ifs("Test.cpp", ios::in);
// 	while (ifs)
// 	{
// 		// get都字符时遇到空格或回车不会停下
// 		char ch = ifs.get();
// 		cout << ch;
// 	}


// 	// 此时ifs文件指针已到尾部，需要clear和seekg进行指针重置
// 	ifs.clear();
// 	// ios::beg状态：从文件头指针开始定位
// 	ifs.seekg(0, ios::beg);


// 	// 以写的方式打开文件
// 	ofstream ofs("D:\\ desktop\test\test-io", ios::out);
// 	while (ifs)
// 	{
// 		char ch = ifs.get();
// 		ofs << ch;
// 	}
// 	return 0;
// }


// struct ServerInfo
// {
// 	char _adress[256];
// 	int _port;
// };

// struct  ConfigManager
// {
// public:
// 	ConfigManager(const char* filename)
// 		: _filename(filename)
// 	{}

// 	// 以二进制的形式写文件
// 	void WriteBin(ServerInfo& info)
// 	{
// 		// 输出文件流要设置二个状态，第一个是默认输出第二个二进制输出
// 		ofstream ofs(_filename, std::ios::out | std::ios::binary);
// 		ofs.write((const char*)&info, sizeof(info));
// 	}

// 	// 以二进制的形式读文件
// 	void ReadBin(ServerInfo& info)
// 	{
// 		// 这里也要设置二个状态，第一个为默认，第二个binary
// 		ifstream ifs(_filename, std::ios::in | std::ios::binary);
// 		ifs.read((char*)&info, sizeof(info));
// 	}

// 	///

// 	// 以文本的方式写文件
// 	void WriteTxt(ServerInfo& info)
// 	{
// 		ofstream ofs(_filename, std::ios::out);
// 		// 注意写到文件要加空格或回车这二个分隔符，不然读文件的时候会读不到，因为读的是以分隔符来判断是否读完
// 		ofs << info._adress << endl;
// 		ofs << info._port << endl;
// 	}

// 	// 以文本的方式读文件
// 	void ReadTxt(ServerInfo& info)
// 	{
// 		ifstream ifs(_filename, std::ios::in);
// 		ifs >> info._adress >> info._port;
// 	}
// public:
// 	string _filename; // 配置文件
// };

// void Test3()
// {
// 	ServerInfo info = { "https://www.bilibili.com/video/BV1Dd4y1U7AE?p=61&spm_id", 100 };
// 	ConfigManager cfm("D:\\test.bin");

// 	// 二进制方式写文件
// 	cfm.WriteBin(info);

// 	// 二进制方式读文件
// 	ServerInfo info2;
// 	cfm.ReadBin(info2);
// 	cout << info2._adress << endl;
// 	cout << info2._port << endl;

// 	///

// 	ServerInfo info3 = { "https://mooc1.chaoxing.com/mycourse/studentstudy?chapterId=444012113&courseId=227786429&clazzid", 200 };
// 	ConfigManager cfm2("D:\\test.txt");

// 	// 以文本的方式写文件
// 	cfm2.WriteTxt(info3);

// 	// 以文本的方式读文件
// 	ServerInfo info4;
// 	cfm2.ReadTxt(info4);
// 	cout << info4._adress << endl;
// 	cout << info4._port << endl;
// }

// #include<sstream>
// int main()
// {
// 	int a = 12345678;
// 	string sa;
// 	// 将一个整形变量转化为字符串，存储到string类对象中
// 	stringstream s;
// 	s << a;
// 	s >> sa;
	
// 	// clear()
// 	// 注意多次转换时，必须使用clear将上次转换状态清空掉
// 	// stringstreams在转换结尾时(即最后一个转换后),会将其内部状态设置为badbit
// 	// 因此下一次转换是必须调用clear()将状态重置为goodbit才可以转换
// 	// 但是clear()不会将stringstreams底层字符串清空掉
	
// 	// s.str("");
// 	// 将stringstream底层管理string对象设置成"",
// 	// 否则多次转换时，会将结果全部累积在底层string对象中
	
// 	s.str("");
// 	s.clear(); // 清空s, 不清空会转化失败
// 	double d = 12.34;
// 	s << d;
// 	s >> sa;
	
// 	string sValue;
// 	sValue = s.str(); // str()方法：返回stringsteam中管理的string类型
// 	cout << sValue << endl;
// 	return 0;
// }

#include<sstream>
#include<iostream>
using namespace std;
// void Test()
// {
// 	stringstream sstream;
// 	// 将多个字符串放入 sstream 中
// 	sstream << "first" << " " << "string,";
// 	sstream << " second string";
// 	cout << "strResult is: " << sstream.str() << endl;

// 	// 清空 sstream
// 	sstream.str("");
// 	sstream << "third string";
// 	cout << "After clear, strResult is: " << sstream.str() << endl;
// }

// int main()
// {
// 	Test();
// }


struct ChatInfo
{
	string _name;	// 名字
	int _id;		// id
	Date _date;		// 时间
	string _msg;	// 聊天信息
};
void Test()
{
	// 结构信息序列化为字符串
	ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧"};
	ostringstream oss;
	oss << winfo._name << " " << winfo._id << " " << winfo._date << " "
		<< winfo._msg;
	string str = oss.str();
	cout << str << endl << endl;

	// 我们通过网络这个字符串发送给对象，实际开发中，信息相对更复杂，
	// 一般会选用Json、xml等方式进行更好的支持
	// 字符串解析成结构信息
	ChatInfo rInfo;
	istringstream iss(str);
	iss >> rInfo._name >> rInfo._id >> rInfo._date >> rInfo._msg;
	cout << "-------------------------------------------------------" << endl;
	cout << "姓名：" << rInfo._name << "(" << rInfo._id << ") ";
	cout << rInfo._date << endl;
	cout << rInfo._name << ":>" << rInfo._msg << endl;
	cout << "-------------------------------------------------------" << endl;
}

int main()
{
	Test();
	return 0;
}

